home *** CD-ROM | disk | FTP | other *** search
/ Info-Mac 4 / Info_Mac IV CD-ROM (Pacific HiTech Inc.)(August 1994).iso / Text Processing / Pairs 1.0 / MPW Tool / Pairs.c < prev    next >
C/C++ Source or Header  |  1994-03-13  |  38KB  |  1,175 lines

  1. // Pairs.c
  2. //
  3. // MPW tool to search for mismatched brace, quote, and comment delimiter pairs
  4.  
  5. #define SystemSevenOrLater 1
  6. #include <ctype.h>
  7. #include <CursorCtl.h>
  8. #include <Dialogs.h>
  9. #include <FCntl.h>
  10. #include <OSEvents.h>
  11. #include <Resources.h>
  12. #include <signal.h>
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <string.h>
  16. #include <Strings.h>
  17. #include <ToolUtils.h>
  18.  
  19. // function prototypes
  20. pascal Boolean DoCustomModalAlertFilter(DialogPtr pdlgAlert,EventRecord *pevntAlert,short *psHit,short sAlertType);
  21. pascal Boolean CustomModalDialogPreprocessFilter(DialogPtr pdlgGeneric,EventRecord *pevntGeneric,short * /*psHit*/);
  22. pascal Boolean CustomModalNoteAlertFilter(DialogPtr pdlgAlert,EventRecord *pevntAlert,short *psHit);
  23. pascal Boolean CustomModalCautionAlertFilter(DialogPtr pdlgAlert,EventRecord *pevntAlert,short *psHit);
  24. pascal Boolean CustomModalStopAlertFilter(DialogPtr pdlgAlert,EventRecord *pevntAlert,short *psHit);
  25. int ReportError(Str255 strError1,Str255 strError2);
  26. void ReportMismatch(Str255 strMismatch);
  27. void ReportNoMismatch(Str255 strNoMismatch);
  28. pascal Boolean DoCustomModalDialogFilter(DialogPtr pdlgGeneric,EventRecord *pevntGeneric,short *psHit);
  29. pascal Boolean CustomModalDialogFilter(DialogPtr pdlgGeneric,EventRecord *pevntGeneric,short *psHit);
  30. Boolean PairsDialog(int *piMode);
  31. Boolean CheckBraces(int iMode,FILE *pfilActive,char *pszFileName,long lStartPos,long lEndPos);
  32. Boolean CheckQuotes(int iMode,FILE *pfilActive,char *pszFileName,long lStartPos,long lEndPos);
  33. Boolean CheckComments(FILE *pfilActive,char *pszFileName,long lStartPos,long lEndPos);
  34. void main(int /*argc*/,char **argv);
  35.  
  36. // alert type constants
  37. #define NOTE_ALERT            0
  38. #define CAUTION_ALERT        2
  39. #define STOP_ALERT            1
  40.  
  41. // edit mode function selection constants
  42. #define MODE_CURLY_BRACE    0
  43. #define MODE_SQUARE_BRACE    1
  44. #define MODE_PARENTHESIS    2
  45. #define MODE_DBL_QUOTE        3
  46. #define MODE_SNGL_QUOTE        4
  47. #define MODE_COMMENT        5
  48.  
  49. // dialog constants
  50. #define ALERT_ID            128
  51. #define DITL_ID                129
  52. #define OK_BUTTON            1
  53. #define CANCEL_BUTTON        2
  54. #define CURLY_BRACE_RADIO    3
  55. #define SQUARE_BRACE_RADIO    4
  56. #define PARENTHESIS_RADIO    5
  57. #define DBL_QUOTE_RADIO        6
  58. #define SNGL_QUOTE_RADIO    7
  59. #define COMMENT_RADIO        8
  60. #define DEFAULT_BUTTON        9
  61. #define RADIO_LABEL            10
  62.  
  63. // brace-related constants
  64. #define NO_ERROR            0
  65. #define BAD_COMMENT            1
  66. #define BAD_LEFT            2
  67. #define BAD_RIGHT            3
  68. #define BAD_NESTED            4
  69. #define BAD_QUOTE            5
  70. #define SLASH                ((int) '/')
  71. #define BACK_SLASH            ((int) '\\')
  72. #define STAR                ((int) '*')
  73. #define SNGL_QUOTE            ((int) '\'')
  74. #define DBL_QUOTE            ((int) '"')
  75. #define EOL                    ((int) '\n')
  76.  
  77. // selection record definition
  78. struct SelectRect
  79.     {
  80.     long lStartingPos;
  81.     long lEndingPos;
  82.     long lDisplayTop;
  83.     };  // SelectRect
  84.  
  85. // global variables
  86. char gachToolName[32];
  87.  
  88. pascal Boolean DoCustomModalAlertFilter(DialogPtr pdlgAlert,EventRecord *pevntAlert,short *psHit,short sAlertType)
  89. // alert input filter which installs standard default and cancel keys, allowing the system modal dialog filter to handle all keydown and update events
  90.  
  91. {
  92. Boolean boolNeedIcon,boolRetVal;
  93. short sIconType;
  94. Handle hTemp;
  95. Rect rctTemp;
  96. GrafPtr pgrfSave;
  97.  
  98. boolRetVal = false;                                                                    // initialize
  99. if (pevntAlert->what == updateEvt)
  100.     {
  101.     if ((WindowPtr) pevntAlert->message == pdlgAlert)
  102.         {
  103.         // most alert updating is automatically handled, but not all. first deal with redrawing the icons in note, caution, and stop alerts
  104.         boolNeedIcon = true;                                                        // initialize
  105.         switch (sAlertType)
  106.             {
  107.             case NOTE_ALERT :
  108.                 {
  109.                 sIconType = noteIcon;                                                // signal what cicn/ICON resource ID is needed
  110.                 break;
  111.                 }  // case NOTE_ALERT
  112.             case CAUTION_ALERT :
  113.                 {
  114.                 sIconType = cautionIcon;                                            // signal what cicn/ICON resource ID is needed
  115.                 break;
  116.                 }  // case CAUTION_ALERT
  117.             case STOP_ALERT :
  118.                 {
  119.                 sIconType = stopIcon;                                                // signal what cicn/ICON resource ID is needed
  120.                 break;
  121.                 }  // case STOP_ALERT
  122.             default :
  123.                 {
  124.                 // plain alert, or who knows what : do nothing
  125.                 boolNeedIcon = false;                                                // signal no icon required
  126.                 break;
  127.                 }  // default;
  128.             }  // switch sAlertType
  129.         if (boolNeedIcon)
  130.             {
  131.             GetPort(&pgrfSave);                                                        // save the current port
  132.             SetPort(pdlgAlert);                                                        // make sure the alert port is the current one
  133.  
  134.             // set standard icon rect
  135.             rctTemp.top = 10;
  136.             rctTemp.left = 20;
  137.             rctTemp.bottom = 42;
  138.             rctTemp.right = 52;
  139.  
  140.             // first try to get a cicn
  141.             hTemp = (Handle) GetCIcon(sIconType);
  142.             if (hTemp != nil)
  143.                 {
  144.                 PlotCIcon(&rctTemp,(CIconHandle) hTemp);                            // plot the cicn
  145.                 DisposeCIcon((CIconHandle) hTemp);                                    // get rid of the cicn handle
  146.                 }  // if hTemp
  147.             else
  148.                 {
  149.                 // try for a B+W icon
  150.                 hTemp = (Handle) GetIcon(sIconType);
  151.                 if (hTemp != nil)
  152.                     {
  153.                     PlotIcon(&rctTemp,hTemp);                                        // plot the ICON
  154.                     ReleaseResource(hTemp);                                            // get rid of the ICON handle
  155.                     }  // if hTemp
  156.                 }  // else if hTemp
  157.             SetPort(pgrfSave);                                                        // restore the old port
  158.             }  // if boolNeedIcon
  159.         
  160.         // the rest (button outlining) is done by calling the standard system dialog handler
  161.         boolRetVal = StdFilterProc(pdlgAlert,pevntAlert,psHit);                        // pass the event info to the standard system dialog handler
  162.         }  // else if pevntAlert->message
  163.     else
  164.         {
  165.         // pass on non-alert update processing as required
  166.         boolRetVal = StdFilterProc(pdlgAlert,pevntAlert,psHit);                        // pass the event info to the standard system dialog handler
  167.         }  // if pevntAlert->message
  168.     }  // if pevntAlert->what
  169. else
  170.     {
  171.     if (((WindowPtr) pevntAlert->message == pdlgAlert) && (pevntAlert->what == activateEvt))
  172.         {
  173.         // this is an activation event - need to setup our special alert button handling
  174.         (void) SetDialogDefaultItem(pdlgAlert,ok);                                    // ensure that the default button is defined
  175.         (void) SetDialogCancelItem(pdlgAlert,ok);                                    // ensure that the cancel button is defined
  176.         }  // if pevntAlert->message
  177.     else
  178.         {
  179.         boolRetVal = CustomModalDialogPreprocessFilter(pdlgAlert,pevntAlert,psHit);    // call the preprocess filter that handles window command-drags
  180.         if (!boolRetVal)
  181.             {
  182.             // the event hasn't been handled yet
  183.             boolRetVal = StdFilterProc(pdlgAlert,pevntAlert,psHit);                    // pass the event info to the standard system dialog handler
  184.             }  // if !boolRetVal;
  185.         }  // else if pevntAlert->message
  186.     }  // else if pevntAlert->what
  187. return boolRetVal;                                                                    // signal if processing is complete
  188. }  // DoCustomModalAlertFilter()
  189.  
  190. pascal Boolean CustomModalDialogPreprocessFilter(DialogPtr pdlgGeneric,EventRecord *pevntGeneric,short * /*psHit*/)
  191. // modal dialog filter function for handling drag events
  192. // note that this function always returns false, allowing it to be used with modal dialogs and alerts
  193. // if it returned true after handling a drag, normal modal dialogs would work OK, but alerts would be dismissed after the drag
  194. // apparently the system dismisses the alert whenever the alert's modal filter function returns true
  195.  
  196. {
  197. short sPart;
  198. WindowPtr pwndEvent;
  199.  
  200. if (pevntGeneric->what == mouseDown)
  201.     {
  202.     // handle a click
  203.     sPart = FindWindow(pevntGeneric->where,&pwndEvent);
  204.     if ((sPart == inDrag) && ((pevntGeneric->modifiers & cmdKey) || (pwndEvent == pdlgGeneric)))
  205.         {
  206.         // allow command-dragging of own application's background windows, or normal dragging of the current window
  207.         DragWindow(pwndEvent,pevntGeneric->where,&qd.screenBits.bounds);
  208.         pevntGeneric->what = nullEvent;            // change to a null-event to prevent beeps, etc.
  209.         }  // if sPart
  210.     }  // if pevntGeneric->what
  211. return false;                                    // signal that the event wasn't handled
  212. }  // CustomModalDialogPreprocessFilter()
  213.  
  214. pascal Boolean CustomModalStopAlertFilter(DialogPtr pdlgAlert,EventRecord *pevntAlert,short *psHit)
  215. // outer shell for the actual stop alert input filter
  216.  
  217. {
  218. Boolean boolRetVal;
  219.  
  220. boolRetVal = DoCustomModalAlertFilter(pdlgAlert,pevntAlert,psHit,STOP_ALERT);    // call the actual modal filter as a separate function, to avoid optimizing compilers from messing up the SetCurrentA4 operation
  221. return boolRetVal;                                                                // signal if processing is complete
  222. }  // CustomModalStopAlertFilter()
  223.  
  224. pascal Boolean CustomModalCautionAlertFilter(DialogPtr pdlgAlert,EventRecord *pevntAlert,short *psHit)
  225. // outer shell for the actual caution alert input filter
  226.  
  227. {
  228. Boolean boolRetVal;
  229.  
  230. boolRetVal = DoCustomModalAlertFilter(pdlgAlert,pevntAlert,psHit,CAUTION_ALERT);    // call the actual modal filter as a separate function, to avoid optimizing compilers from messing up the SetCurrentA4 operation
  231. return boolRetVal;                                                                    // signal if processing is complete
  232. }  // CustomModalStopAlertFilter()
  233.  
  234. pascal Boolean CustomModalNoteAlertFilter(DialogPtr pdlgAlert,EventRecord *pevntAlert,short *psHit)
  235. // outer shell for the actual note alert input filter
  236.  
  237. {
  238. Boolean boolRetVal;
  239. boolRetVal = DoCustomModalAlertFilter(pdlgAlert,pevntAlert,psHit,NOTE_ALERT);    // call the actual modal filter as a separate function, to avoid optimizing compilers from messing up the SetCurrentA4 operation
  240. return boolRetVal;                                                                // signal if processing is complete
  241. }  // CustomModalNoteAlertFilter()
  242.  
  243. int ReportError(Str255 strError1,Str255 strError2)
  244. // put up an error dialog
  245.  
  246. {
  247. ModalFilterUPP umfAlert;
  248.  
  249. SetCursor(&qd.arrow);                                            // replace MPW beach ball cursor with arrow
  250. (void) signal(SIGINT,SIG_IGN);                                    // disable command-period abort when alert is displayed
  251. umfAlert = NewModalFilterProc(CustomModalStopAlertFilter);        // get a routine descriptor (or UniversalProcPtr for 68k) for the stop alert dialog filter function
  252. ParamText("\pPairs",strError1,strError2,"\p");
  253. (void) StopAlert(ALERT_ID,umfAlert);
  254. DisposeRoutineDescriptor((UniversalProcPtr) umfAlert);            // dispose of the routine descriptor
  255. (void) signal(SIGINT,SIG_DFL);                                    // re-enable command-period abort
  256. return 1;                                                        // return error code
  257. }  // ReportError()
  258.  
  259. void ReportMismatch(Str255 strMismatch)
  260. // put up a pair check status dialog
  261.  
  262. {
  263. ModalFilterUPP umfAlert;
  264.  
  265. SetCursor(&qd.arrow);                                            // replace MPW beach ball cursor with arrow
  266. (void) signal(SIGINT,SIG_IGN);                                    // disable command-period abort when alert is displayed
  267. umfAlert = NewModalFilterProc(CustomModalCautionAlertFilter);    // get a routine descriptor (or UniversalProcPtr for 68k) for the caution alert dialog filter function
  268. ParamText("\pPairs",strMismatch,"\p","\p");
  269. (void) CautionAlert(ALERT_ID,umfAlert);
  270. DisposeRoutineDescriptor((UniversalProcPtr) umfAlert);            // dispose of the routine descriptor
  271. (void) signal(SIGINT,SIG_DFL);                                    // re-enable command-period abort
  272. }  // ReportMismatch()
  273.  
  274. void ReportNoMismatch(Str255 strNoMismatch)
  275. // put up a pair check status dialog
  276.  
  277. {
  278. ModalFilterUPP umfAlert;
  279.  
  280. SetCursor(&qd.arrow);                                            // replace MPW beach ball cursor with arrow
  281. (void) signal(SIGINT,SIG_IGN);                                    // disable command-period abort when alert is displayed
  282. umfAlert = NewModalFilterProc(CustomModalNoteAlertFilter);        // get a routine descriptor (or UniversalProcPtr for 68k) for the note alert dialog filter function
  283. ParamText("\pPairs",strNoMismatch,"\p","\p");
  284. (void) NoteAlert(ALERT_ID,umfAlert);
  285. DisposeRoutineDescriptor((UniversalProcPtr) umfAlert);            // dispose of the routine descriptor
  286. (void) signal(SIGINT,SIG_DFL);                                    // re-enable command-period abort
  287. }  // ReportNoMismatch()
  288.  
  289. static pascal Boolean DoCustomModalDialogFilter(DialogPtr pdlgGeneric,EventRecord *pevntGeneric,short *psHit)
  290. // dialog input filter
  291.  
  292. {
  293. Boolean boolRetVal;
  294.  
  295. boolRetVal = false;                                                                        // initialize
  296. if (pevntGeneric->what == updateEvt)
  297.     {
  298.     boolRetVal = StdFilterProc(pdlgGeneric,pevntGeneric,psHit);                            // pass the event info to the standard system dialog handler
  299.     }  // if pevntGeneric->what
  300. else
  301.     {
  302.     boolRetVal = CustomModalDialogPreprocessFilter(pdlgGeneric,pevntGeneric,psHit);        // call the preprocess filter that handles window command-drags
  303.     if (!boolRetVal)
  304.         {
  305.         // the event hasn't been handled yet
  306.         boolRetVal = StdFilterProc(pdlgGeneric,pevntGeneric,psHit);                        // pass the event info to the standard system dialog handler
  307.         }  // if !boolRetVal
  308.     }  // else if pevntGeneric->what
  309. return boolRetVal;                                                                        // signal if processing is complete
  310. }  // DoCustomModalDialogFilter()
  311.  
  312. pascal Boolean CustomModalDialogFilter(DialogPtr pdlgGeneric,EventRecord *pevntGeneric,short *psHit)
  313. // outer shell for the actual dialog input filter
  314.  
  315. {
  316. Boolean boolRetVal;
  317.  
  318. boolRetVal = DoCustomModalDialogFilter(pdlgGeneric,pevntGeneric,psHit);        // call the actual modal filter as a separate function, to avoid optimizing compilers from messing up the SetCurrentA4 operation
  319. return boolRetVal;                                                            // signal if processing is complete
  320. }  // CustomModalDialogFilter()
  321.  
  322. Boolean PairsDialog(int *piMode)
  323. // Pairs edit dialog box routine
  324.  
  325. {
  326. Boolean boolRetVal;
  327. short sDummy,sIndex,sHit,sTemp;
  328. DialogPtr pdlogPairs;
  329. Rect rectTemp;
  330. Handle hdlogItem;
  331. ControlHandle hctrlItem,hctrlTemp;
  332. ModalFilterUPP umfDialog;
  333.  
  334. (void) signal(SIGINT,SIG_IGN);                                                                                            // disable command-period abort when dialog is displayed
  335. pdlogPairs = GetNewDialog(DITL_ID,NULL,(WindowPtr) -1);                                                                    // bring in the dialog resource
  336. if (pdlogPairs != NULL)
  337.     {
  338.     SetPort(pdlogPairs);                                                                                                // ensure the correct port is current
  339.     (void) SetDialogDefaultItem(pdlogPairs,ok);                                                                            // ensure that the default button is defined
  340.     (void) SetDialogCancelItem(pdlogPairs,cancel);                                                                        // ensure that the cancel button is defined
  341.     umfDialog = NewModalFilterProc(CustomModalDialogFilter);                                                            // get a routine descriptor (or UniversalProcPtr for 68k) for the custom dialog filter function
  342.     
  343.     // set up radio buttons to a default value
  344.     for (sIndex = CURLY_BRACE_RADIO; sIndex <= COMMENT_RADIO; sIndex++)
  345.         {
  346.         // clear all radios
  347.         GetDialogItem(pdlogPairs,sIndex,&sDummy,&hdlogItem,&rectTemp);                                                    // get the item handle
  348.         hctrlTemp = (ControlHandle) hdlogItem;                                                                            // get the control handle
  349.         SetControlValue(hctrlTemp,0);                                                                                    // turn the radio selection off
  350.         }  // for sIndex
  351.     GetDialogItem(pdlogPairs,CURLY_BRACE_RADIO,&sDummy,&hdlogItem,&rectTemp);                                            // get the item handle
  352.     hctrlItem = (ControlHandle) hdlogItem;                                                                                // get the control handle
  353.     SetControlValue(hctrlItem,1);                                                                                        // select the radio
  354.     
  355.     ShowWindow(pdlogPairs);                                                                                                // open a dialog box
  356.     SelectWindow(pdlogPairs);                                                                                             // make it visible
  357.     
  358.     do
  359.         {
  360.         ModalDialog(umfDialog,&sHit);                                                                                    // wait until an item is hit
  361.         GetDialogItem(pdlogPairs,sHit,&sDummy,&hdlogItem,&rectTemp);                                                     // get item information
  362.         hctrlItem = (ControlHandle) hdlogItem;                                                                            // get the control handle
  363.         
  364.         switch (sHit)
  365.             {
  366.             case CURLY_BRACE_RADIO :
  367.             case SQUARE_BRACE_RADIO :
  368.             case PARENTHESIS_RADIO :
  369.             case DBL_QUOTE_RADIO :
  370.             case SNGL_QUOTE_RADIO :
  371.             case COMMENT_RADIO :
  372.                 {
  373.                 for (sIndex = CURLY_BRACE_RADIO; sIndex <= COMMENT_RADIO; sIndex++)
  374.                     {
  375.                     // clear all radios
  376.                     GetDialogItem(pdlogPairs,sIndex,&sDummy,&hdlogItem,&rectTemp);                                        // get the item handle
  377.                     hctrlTemp = (ControlHandle) hdlogItem;                                                                // get the control handle
  378.                     SetControlValue(hctrlTemp,0);                                                                        // turn the radio selection off
  379.                     }  // for sIndex
  380.                 SetControlValue(hctrlItem,1);                                                                            // turn the one radio selection on
  381.                 break;
  382.                 }  // case CURLY_BRACE_RADIO … COMMENT_RADIO
  383.             }  // switch sHit
  384.         }  // do
  385.     while ((sHit != OK_BUTTON) && (sHit != CANCEL_BUTTON));
  386.     
  387.     // Get results after dialog
  388.     if (sHit == CANCEL_BUTTON)
  389.         {
  390.         boolRetVal = true;
  391.         }  // if sHit
  392.     else
  393.         {
  394.         boolRetVal = false;
  395.         }  // else if sHit
  396.     if (!boolRetVal)
  397.         {
  398.         sIndex = CURLY_BRACE_RADIO;                                                                                        // start at the first radio in this group
  399.         do
  400.             {
  401.             GetDialogItem(pdlogPairs,sIndex,&sDummy,&hdlogItem,&rectTemp);                                                // get the item handle
  402.             hctrlItem = (ControlHandle) hdlogItem;                                                                        // get the control handle
  403.             sTemp = GetControlValue(hctrlItem);                                                                            // get the radio value
  404.             sIndex++;
  405.             }  // do
  406.         while ((sTemp != 1) && (sIndex <= COMMENT_RADIO));
  407.         *piMode = sIndex - CURLY_BRACE_RADIO - 1;
  408.         boolRetVal = false;
  409.         }  // if !boolRetVal
  410.     DisposeDialog(pdlogPairs);                                                                                             // flush the dialog out of memory
  411.     DisposeRoutineDescriptor((UniversalProcPtr) umfDialog);                                                                // dispose of the routine descriptor
  412.     }  // if pdlogPairs
  413. else
  414.     {
  415.     ReportError("\pUnable to continue:","\pCan't create the dialog box.");
  416.     boolRetVal = false;                                                                                                    // signal don't continue
  417.     }  // else if pdlogPairs
  418. (void) signal(SIGINT,SIG_DFL);                                                                                            // re-enable command-period abort
  419. return boolRetVal;
  420. }  // PairsDialog()
  421.  
  422. Boolean CheckBraces(int iMode,FILE *pfilActive,char *pszFileName,long lStartPos,long lEndPos)
  423. // find mismatched curly and square brackets and parenthesis
  424.  
  425. {
  426. Boolean fDone,fIn1Quote,fIn2Quote,fInCComment,fInCPlusComment,fMismatch,fSelect;
  427. int iCurrent,iError,iLastChar,iLeftMatch,iRightMatch,iSecondToLastChar;
  428. long lCurPos,lMatch,lSavePos;
  429. struct SelectRect srectTemp;
  430.  
  431. switch(iMode)
  432.     {
  433.     case MODE_CURLY_BRACE :
  434.         {
  435.         iLeftMatch = (int) '{';
  436.         iRightMatch = (int) '}';
  437.         break;
  438.         }  // case MODE_CURLY_BRACE
  439.     case MODE_SQUARE_BRACE :
  440.         {
  441.         iLeftMatch = (int) '[';
  442.         iRightMatch = (int) ']';
  443.         break;
  444.         }  // case MODE_SQUARE_BRACE
  445.     case MODE_PARENTHESIS :
  446.         {
  447.         iLeftMatch = (int) '(';
  448.         iRightMatch = (int) ')';
  449.         break;
  450.         }  // case MODE_PARENTHESIS
  451.     default :
  452.         {
  453.         // do nothing
  454.         break;
  455.         }  // default
  456.     }  // switch iMode
  457. fSelect = (lEndPos > lStartPos);
  458. fMismatch = true;
  459. fDone = false;
  460. fIn1Quote = false;
  461. fIn2Quote = false;
  462. fInCComment = false;
  463. fInCPlusComment = false;
  464. iSecondToLastChar = 0;
  465. iLastChar = 0;
  466. lCurPos = lStartPos;
  467. lMatch = 0L;
  468. iError = NO_ERROR;
  469. lSavePos = lStartPos;
  470.  
  471. while(!fDone)
  472.     {
  473.     iCurrent = fgetc(pfilActive);                                // read a single character
  474.     if (!feof(pfilActive))
  475.         {
  476.         if (iCurrent == iLeftMatch)
  477.             {
  478.             if (!fIn1Quote && !fIn2Quote && !fInCComment && !fInCPlusComment)
  479.                 {
  480.                 lMatch++;                                        // increment the pair count
  481.                 if (lMatch == 1)
  482.                     {
  483.                     lSavePos = lCurPos;                            // save the current character number
  484.                     }  // if lMatch
  485.                 }  // if !fIn1Quote
  486.             }  // if iCurrent
  487.         else
  488.             {
  489.             if (iCurrent == iRightMatch)
  490.                 {
  491.                 if (!fIn1Quote && !fIn2Quote && !fInCComment && !fInCPlusComment)
  492.                     {
  493.                     lMatch--;                                    // decrement the pair count
  494.                     if (lMatch  < 0)
  495.                         {
  496.                         fDone = true;                            // signal quit
  497.                         iError = BAD_RIGHT;                        // signal mismatched right pair
  498.                         }  // if lMatch
  499.                     }  // if !fIn1Quote
  500.                 }  // if iCurrent
  501.             else
  502.                 {
  503.                 switch(iCurrent)
  504.                     {
  505.                     case SNGL_QUOTE :
  506.                         {
  507.                         if (!fIn2Quote && !fInCComment && !fInCPlusComment)
  508.                             {
  509.                             if (!(fIn1Quote && (iLastChar == BACK_SLASH) && (iSecondToLastChar != BACK_SLASH)))
  510.                                 {
  511.                                 // this is not an escaped quote
  512.                                 fIn1Quote = !fIn1Quote;            // toggle the "in single quote" status
  513.                                 }  // if !fInQuote1
  514.                             }  // if !fIn2Quote
  515.                             break;
  516.                         }  // case SNGL_QUOTE
  517.                     case DBL_QUOTE :
  518.                         {
  519.                         if (!fIn1Quote && !fInCComment && !fInCPlusComment)
  520.                             {
  521.                             if (!(fIn2Quote && (iLastChar == BACK_SLASH) && (iSecondToLastChar != BACK_SLASH)))
  522.                                 {
  523.                                 // this is not an escaped quote
  524.                                 fIn2Quote = !fIn2Quote;            // toggle the "in double quote" status
  525.                                 }  // if !fInQuote1
  526.                             }  // if !fIn1Quote
  527.                         break;
  528.                         }  // case DBL_QUOTE
  529.                     case SLASH :
  530.                         {
  531.                         if (!fIn1Quote && !fIn2Quote && !fInCPlusComment)
  532.                             {
  533.                             if (iLastChar == SLASH)
  534.                                 {
  535.                                 if (!fInCComment)
  536.                                     {
  537.                                     fInCPlusComment = true;        // set C++-style comment flag
  538.                                     }  // if !fInCComment
  539.                                 }  // if iLastChar
  540.                             else
  541.                                 {
  542.                                 if (iLastChar == STAR)
  543.                                     {
  544.                                     if (fInCComment)
  545.                                         {
  546.                                         fInCComment = false;    // clear C-style comment flag
  547.                                         iLastChar = '\0';        // impose safe dummy value to prevent recognizing *// as a close C and open C++ comment
  548.                                         iCurrent = '\0';        // impose safe dummy value to prevent recognizing *// as a close C and open C++ comment
  549.                                         }  // if fInCComment
  550.                                     else
  551.                                         {
  552.                                         // mismatched comments
  553.                                         fDone = true;            // signal quit
  554.                                         iError = BAD_COMMENT;    // signal mismatched comment
  555.                                         }  // else if fInCComment
  556.                                     }  // if iLastChar
  557.                                 }  // else if iLastChar
  558.                             }  // if !fIn1Quote
  559.                         break;
  560.                         }  // case SLASH
  561.                     case STAR :
  562.                         {
  563.                         if (!fIn1Quote && !fIn2Quote && !fInCPlusComment)
  564.                             {
  565.                             if (iLastChar == SLASH)
  566.                                 {
  567.                                 if (!fInCComment)
  568.                                     {
  569.                                     fInCComment = true;            // set C-style comment flag
  570.                                     iLastChar = '\0';            // impose safe dummy value to prevent recognizing /*/ as an open and close comment
  571.                                     iCurrent = '\0';            // impose safe dummy value to prevent recognizing /*/ as an open and close comment
  572.                                     }  // if !fInCComment
  573.                                 else
  574.                                     {
  575.                                     // nested C-style comments - a no-no
  576.                                     fDone = true;                // signal quit
  577.                                     iError = BAD_NESTED;        // signal nested comments
  578.                                     }  // else if !fInCComment
  579.                                 }  // if iLastChar
  580.                             }  // if !fIn1Quote
  581.                         break;
  582.                         }  // case STAR
  583.                     case EOL :
  584.                         {
  585.                         fInCPlusComment = false;
  586.                         SpinCursor(1);
  587.                         break;
  588.                         }  // case EOL
  589.                     default :
  590.                         {
  591.                         // do nothing
  592.                         break;
  593.                         }  // default
  594.                     }  // switch iCurrent
  595.                 }  // else if iCurrent
  596.             }  // else if iCurrent
  597.         lCurPos++;                                                // increment the current character position
  598.         iSecondToLastChar = iLastChar;                            // save the second-to-last-read character
  599.         iLastChar = iCurrent;                                    // save the last-read character
  600.         if (fSelect && (lCurPos >= lEndPos))
  601.             {
  602.             fDone = true;                                        // all characters have been read
  603.             }  // if fSelect
  604.         }  // if !feof()
  605.     else
  606.         {
  607.         fDone = true;                                            // all characters have been read
  608.         }  // else if !feof()
  609.     }  // while !fDone
  610. if ((iError == NO_ERROR) && (lMatch > 0))
  611.     {
  612.     iError = BAD_LEFT;                                            // signal mismatched left pair
  613.     }  // if !iError
  614. switch(iError)
  615.     {
  616.     case BAD_LEFT :
  617.         {
  618.         ReportMismatch("\pMismatched left brace found!");
  619.         srectTemp.lDisplayTop = -1;                                // minimize scrolling
  620.         srectTemp.lStartingPos = lSavePos;
  621.         srectTemp.lEndingPos = lSavePos + 1;
  622.         iError = faccess(pszFileName,F_SSELINFO,(long *)&srectTemp);
  623.         if (iError)
  624.             {
  625.             (void) ReportError("\pCan't select the mismatched brace","\p");
  626.             }  // if iError
  627.         break;
  628.         }  // case BAD_LEFT
  629.     case BAD_RIGHT :
  630.         {
  631.         ReportMismatch("\pMismatched right brace found!");
  632.         srectTemp.lDisplayTop = -1;                                // minimize scrolling
  633.         srectTemp.lStartingPos = lCurPos - 1;
  634.         srectTemp.lEndingPos = lCurPos;
  635.         iError = faccess(pszFileName,F_SSELINFO,(long *)&srectTemp);
  636.         if (iError)
  637.             {
  638.             (void) ReportError("\pCan't select the mismatched brace","\p");
  639.             }  // if iError
  640.         break;
  641.         }  // case BAD_RIGHT
  642.     case BAD_NESTED :
  643.         {
  644.         ReportMismatch("\pNested C-style “/* */” comment found!");
  645.         srectTemp.lDisplayTop = -1;                                // minimize scrolling
  646.         srectTemp.lStartingPos = lCurPos - 2;
  647.         srectTemp.lEndingPos = lCurPos;
  648.         iError = faccess(pszFileName,F_SSELINFO,(long *)&srectTemp);
  649.         if (iError)
  650.             {
  651.             (void) ReportError("\pCan't select the nested comment","\p");
  652.             }  // if iError
  653.         break;
  654.         }  // case BAD_NESTED
  655.     case BAD_COMMENT :
  656.         {
  657.         ReportMismatch("\pMismatched C-style “/* */” comment found!");
  658.         srectTemp.lDisplayTop = -1;                                // minimize scrolling
  659.         srectTemp.lStartingPos = lCurPos - 2;
  660.         srectTemp.lEndingPos = lCurPos;
  661.         iError = faccess(pszFileName,F_SSELINFO,(long *)&srectTemp);
  662.         if (iError)
  663.             {
  664.             (void) ReportError("\pCan't select the mismatched comment","\p");
  665.             }  // if iError
  666.         break;
  667.         }  // case BAD_COMMENT
  668.     default :
  669.         {
  670.         // no mismatched pairs
  671.         ReportNoMismatch("\pNo mismatched pairs found!");
  672.         fMismatch = false;
  673.         break;
  674.         }  // default
  675.     }  // switch iError
  676. return fMismatch;
  677. }  // CheckBraces()
  678.  
  679. Boolean CheckQuotes(int iMode,FILE *pfilActive,char *pszFileName,long lStartPos,long lEndPos)
  680. // find lines having an odd number of single or double quotes
  681.  
  682. {
  683. Boolean fDone,fInQuote,fInCComment,fInCPlusComment,fMismatch,fSelect;
  684. int iCurrent,iError,iLastChar,iMatch,iQuote,iSecondToLastChar;
  685. long lCurPos,lMatch,lSavePos;
  686. struct SelectRect srectTemp;
  687.  
  688. switch(iMode)
  689.     {
  690.     case MODE_DBL_QUOTE :
  691.         {
  692.         iMatch = DBL_QUOTE;
  693.         iQuote = SNGL_QUOTE;
  694.         break;
  695.         }  // case MODE_DBL_QUOTE
  696.     case MODE_SNGL_QUOTE :
  697.         {
  698.         iMatch = SNGL_QUOTE;
  699.         iQuote = DBL_QUOTE;
  700.         break;
  701.         }  // case MODE_SNGL_QUOTE
  702.     default :
  703.         {
  704.         // do nothing
  705.         break;
  706.         }  // default
  707.     }  // switch iMode
  708. fSelect = (lEndPos > lStartPos);
  709. fMismatch = true;
  710. fDone = false;
  711. fInQuote = false;
  712. fInCComment = false;
  713. fInCPlusComment = false;
  714. iSecondToLastChar = 0;
  715. iLastChar = 0;
  716. lCurPos = lStartPos;
  717. lMatch = 0L;
  718. iError = NO_ERROR;
  719. lSavePos = lStartPos;
  720.  
  721. while(!fDone)
  722.     {
  723.     iCurrent = fgetc(pfilActive);                                // read a single character
  724.     if (!feof(pfilActive))
  725.         {
  726.         if (iCurrent == iMatch)
  727.             {
  728.             if (!fInQuote && !fInCComment && !fInCPlusComment)
  729.                 {
  730.                 if (!((lMatch & 1L) && (iLastChar == BACK_SLASH) && (iSecondToLastChar != BACK_SLASH)))
  731.                     {
  732.                     // this is not an escaped quote
  733.                     lMatch++;                                    // increment the pair count
  734.                     }  // if lMatch
  735.                 }  // if fInQuote
  736.             }  // if iCurrent
  737.         else
  738.             {
  739.             if (iCurrent == iQuote)
  740.                 {
  741.                 if (!fInCComment && !fInCPlusComment && !(lMatch & 1L))
  742.                     {
  743.                     if (!(fInQuote && (iLastChar == BACK_SLASH) && (iSecondToLastChar != BACK_SLASH)))
  744.                         {
  745.                         // this is not an escaped quote
  746.                         fInQuote = !fInQuote;                    // toggle the "in quote" status
  747.                         }  // if !fInQuote
  748.                     }  // if !fIncComment
  749.                 }  // if iCurrent
  750.             else
  751.                 {
  752.                 switch(iCurrent)
  753.                     {
  754.                     case SLASH :
  755.                         {
  756.                         if (!fInQuote && !(lMatch & 1L) && !fInCPlusComment)
  757.                             {
  758.                             if (iLastChar == SLASH)
  759.                                 {
  760.                                 if (!fInCComment)
  761.                                     {
  762.                                     fInCPlusComment = true;        // set C++-style comment flag
  763.                                     }  // if !fInCComment
  764.                                 }  // if iLastChar
  765.                             else
  766.                                 {
  767.                                 if (iLastChar == STAR)
  768.                                     {
  769.                                     if (fInCComment)
  770.                                         {
  771.                                         fInCComment = false;    // clear C-style comment flag
  772.                                         iLastChar = '\0';        // impose safe dummy value to prevent recognizing *// as a close C and open C++ comment
  773.                                         iCurrent = '\0';        // impose safe dummy value to prevent recognizing *// as a close C and open C++ comment
  774.                                         }  // if fInCComment
  775.                                     else
  776.                                         {
  777.                                         // mismatched comments
  778.                                         fDone = true;            // signal quit
  779.                                         iError = BAD_COMMENT;    // signal mismatched comment
  780.                                         }  // else if fInCComment
  781.                                     }  // if iLastChar
  782.                                 }  // else if iLastChar
  783.                             }  // if !fInQuote
  784.                         break;
  785.                         }  // case SLASH
  786.                     case STAR :
  787.                         {
  788.                         if (!fInQuote && !(lMatch & 1L) && !fInCPlusComment)
  789.                             {
  790.                             if (iLastChar == SLASH)
  791.                                 {
  792.                                 if (!fInCComment)
  793.                                     {
  794.                                     fInCComment = true;            // set C-style comment flag
  795.                                     iLastChar = '\0';            // impose safe dummy value to prevent recognizing /*/ as an open and close comment
  796.                                     iCurrent = '\0';            // impose safe dummy value to prevent recognizing /*/ as an open and close comment
  797.                                     }  // if !fInCComment
  798.                                 else
  799.                                     {
  800.                                     // nested C-style comments - a no-no
  801.                                     fDone = true;                // signal quit
  802.                                     iError = BAD_NESTED;        // signal nested comments
  803.                                     }  // else if !fInCComment
  804.                                 }  // if iLastChar
  805.                             }  // if !fInQuote
  806.                         break;
  807.                         }  // case STAR
  808.                     case EOL :
  809.                         {
  810.                         fInCPlusComment = false;
  811.                         if (lMatch & 1L)
  812.                             {
  813.                             fDone = true;
  814.                             iError = BAD_QUOTE;                    // signal odd number of quotes
  815.                             }  // if lMatch
  816.                         else
  817.                             {
  818.                             lSavePos = lCurPos + 1;                // save the new start of line position
  819.                             }  // else if lMatch
  820.                         fInQuote = false;
  821.                         SpinCursor(1);
  822.                         break;
  823.                         }  // case EOL
  824.                     default :
  825.                         {
  826.                         // do nothing
  827.                         break;
  828.                         }  // default
  829.                     }  // switch iCurrent
  830.                 }  // else if iCurrent
  831.             }  // else if iCurrent
  832.         lCurPos++;                                                // increment the current character position
  833.         iSecondToLastChar = iLastChar;                            // save the second-to-last-read character
  834.         iLastChar = iCurrent;                                    // save the last-read character
  835.         if (fSelect && (lCurPos >= lEndPos))
  836.             {
  837.             fDone = true;                                        // all characters have been read
  838.             }  // if fSelect
  839.         }  // if !feof()
  840.     else
  841.         {
  842.         fDone = true;                                            // all characters have been read
  843.         }  // else if !feof()
  844.     }  // while !fDone
  845. if ((iError == NO_ERROR) && (lMatch & 1L))
  846.     {
  847.     iError = BAD_QUOTE;                                            // signal odd number of quotes
  848.     }  // if !iError
  849. switch(iError)
  850.     {
  851.     case BAD_QUOTE :
  852.         {
  853.         ReportMismatch("\pOdd number of quote characters found in a line!");
  854.         srectTemp.lDisplayTop = -1;                                // minimize scrolling
  855.         srectTemp.lStartingPos = lSavePos;
  856.         srectTemp.lEndingPos = lCurPos;
  857.         iError = faccess(pszFileName,F_SSELINFO,(long *)&srectTemp);
  858.         if (iError)
  859.             {
  860.             (void) ReportError("\pCan't select the bad line","\p");
  861.             }  // if iError
  862.         break;
  863.         }  // case BAD_RIGHT
  864.     case BAD_NESTED :
  865.         {
  866.         ReportMismatch("\pNested C-style “/* */” comment found!");
  867.         srectTemp.lDisplayTop = -1;                                // minimize scrolling
  868.         srectTemp.lStartingPos = lCurPos - 2;
  869.         srectTemp.lEndingPos = lCurPos;
  870.         iError = faccess(pszFileName,F_SSELINFO,(long *)&srectTemp);
  871.         if (iError)
  872.             {
  873.             (void) ReportError("\pCan't select the nested comment","\p");
  874.             }  // if iError
  875.         break;
  876.         }  // case BAD_NESTED
  877.     case BAD_COMMENT :
  878.         {
  879.         ReportMismatch("\pMismatched C-style “/* */” comment found!");
  880.         srectTemp.lDisplayTop = -1;                                // minimize scrolling
  881.         srectTemp.lStartingPos = lCurPos - 2;
  882.         srectTemp.lEndingPos = lCurPos;
  883.         iError = faccess(pszFileName,F_SSELINFO,(long *)&srectTemp);
  884.         if (iError)
  885.             {
  886.             (void) ReportError("\pCan't select the mismatched comment","\p");
  887.             }  // if iError
  888.         break;
  889.         }  // case BAD_COMMENT
  890.     default :
  891.         {
  892.         // no mismatched pairs
  893.         fMismatch = false;
  894.         ReportNoMismatch("\pNo lines containing an odd number of quotes found!");
  895.         break;
  896.         }  // default
  897.     }  // switch iError
  898. return fMismatch;
  899. }  // CheckQuotes()
  900.  
  901. Boolean CheckComments(FILE *pfilActive,char *pszFileName,long lStartPos,long lEndPos)
  902. // find mismatched C-style comments
  903.  
  904. {
  905. Boolean fDone,fIn1Quote,fIn2Quote,fInCComment,fInCPlusComment,fMismatch,fSelect;
  906. int iCurrent,iError,iLastChar,iSecondToLastChar;
  907. long lCurPos,lMatch,lSavePos;
  908. struct SelectRect srectTemp;
  909.  
  910. fMismatch = true;
  911. fSelect = (lEndPos > lStartPos);
  912. fDone = false;
  913. fIn1Quote = false;
  914. fIn2Quote = false;
  915. fInCComment = false;
  916. fInCPlusComment = false;
  917. iSecondToLastChar = 0;
  918. iLastChar = 0;
  919. lCurPos = lStartPos;
  920. lMatch = 0L;
  921. iError = NO_ERROR;
  922. lSavePos = lStartPos;
  923.  
  924. while(!fDone)
  925.     {
  926.     iCurrent = fgetc(pfilActive);                        // read a single character
  927.     if (!feof(pfilActive))
  928.         {
  929.         switch(iCurrent)
  930.             {
  931.             case SNGL_QUOTE :
  932.                 {
  933.                 if (!fIn2Quote && !fInCComment && !fInCPlusComment)
  934.                     {
  935.                     if (!(fIn1Quote && (iLastChar == BACK_SLASH) && (iSecondToLastChar != BACK_SLASH)))
  936.                         {
  937.                         // this is not an escaped quote
  938.                         fIn1Quote = !fIn1Quote;            // toggle the "in single quote" status
  939.                         }  // if !fInQuote1
  940.                     }  // if !fIn2Quote
  941.                     break;
  942.                 }  // case SNGL_QUOTE
  943.             case DBL_QUOTE :
  944.                 {
  945.                 if (!fIn1Quote && !fInCComment && !fInCPlusComment)
  946.                     {
  947.                     if (!(fIn2Quote && (iLastChar == BACK_SLASH) && (iSecondToLastChar != BACK_SLASH)))
  948.                         {
  949.                         // this is not an escaped quote
  950.                         fIn2Quote = !fIn2Quote;            // toggle the "in single quote" status
  951.                         }  // if !fInQuote1
  952.                     }  // if !fIn1Quote
  953.                 break;
  954.                 }  // case DBL_QUOTE
  955.             case SLASH :
  956.                 {
  957.                 if (!fIn1Quote && !fIn2Quote && !fInCPlusComment)
  958.                     {
  959.                     if (iLastChar == SLASH)
  960.                         {
  961.                         if (!fInCComment)
  962.                             {
  963.                             fInCPlusComment = true;        // set C++-style comment flag
  964.                             }  // if !fInCComment
  965.                         }  // if iLastChar
  966.                     else
  967.                         {
  968.                         if (iLastChar == STAR)
  969.                             {
  970.                             if (fInCComment)
  971.                                 {
  972.                                 fInCComment = false;    // clear C-style comment flag
  973.                                 iLastChar = '\0';        // impose safe dummy value to prevent recognizing *// as a close C and open C++ comment
  974.                                 iCurrent = '\0';        // impose safe dummy value to prevent recognizing *// as a close C and open C++ comment
  975.                                 }  // if fInCComment
  976.                             else
  977.                                 {
  978.                                 // mismatched comments
  979.                                 fDone = true;            // signal quit
  980.                                 iError = BAD_RIGHT;        // signal mismatched comment
  981.                                 }  // else if fInCComment
  982.                             }  // if iLastChar
  983.                         }  // else if iLastChar
  984.                     }  // if !fIn1Quote
  985.                 break;
  986.                 }  // case SLASH
  987.             case STAR :
  988.                 {
  989.                 if (!fIn1Quote && !fIn2Quote && !fInCPlusComment)
  990.                     {
  991.                     if (iLastChar == SLASH)
  992.                         {
  993.                         if (!fInCComment)
  994.                             {
  995.                             fInCComment = true;            // set C-style comment flag
  996.                             iLastChar = '\0';            // impose safe dummy value to prevent recognizing /*/ as an open and close comment
  997.                             iCurrent = '\0';            // impose safe dummy value to prevent recognizing /*/ as an open and close comment
  998.                             lSavePos = lCurPos;            // save the current character number
  999.                             }  // if !fInCComment
  1000.                         else
  1001.                             {
  1002.                             // nested C-style comments - a no-no
  1003.                             fDone = true;                // signal quit
  1004.                             iError = BAD_NESTED;        // signal nested comments
  1005.                             }  // else if !fInCComment
  1006.                         }  // if iLastChar
  1007.                     }  // if !fIn1Quote
  1008.                 break;
  1009.                 }  // case STAR
  1010.             case EOL :
  1011.                 {
  1012.                 fInCPlusComment = false;
  1013.                 SpinCursor(1);
  1014.                 break;
  1015.                 }  // case EOL
  1016.             default :
  1017.                 {
  1018.                 // do nothing
  1019.                 break;
  1020.                 }  // default
  1021.             }  // switch iCurrent
  1022.         lCurPos++;                                                // increment the current character position
  1023.         iSecondToLastChar = iLastChar;                            // save the second-to-last-read character
  1024.         iLastChar = iCurrent;                                    // save the last-read character
  1025.         if (fSelect && (lCurPos >= lEndPos))
  1026.             {
  1027.             fDone = true;                                        // all characters have been read
  1028.             }  // if fSelect
  1029.         }  // if !feof()
  1030.     else
  1031.         {
  1032.         fDone = true;                                            // all characters have been read
  1033.         }  // else if !feof()
  1034.     }  // while !fDone
  1035. if ((iError == NO_ERROR) && fInCComment)
  1036.     {
  1037.     iError = BAD_LEFT;                                            // signal mis-matched left pair
  1038.     }  // if !iError
  1039. switch(iError)
  1040.     {
  1041.     case BAD_LEFT :
  1042.         {
  1043.         ReportMismatch("\pMismatched left comment found!");
  1044.         srectTemp.lDisplayTop = -1;                                // minimize scrolling
  1045.         srectTemp.lStartingPos = lSavePos - 1;
  1046.         srectTemp.lEndingPos = lSavePos + 1;
  1047.         iError = faccess(pszFileName,F_SSELINFO,(long *)&srectTemp);
  1048.         if (iError)
  1049.             {
  1050.             (void) ReportError("\pCan't select the mismatched comment","\p");
  1051.             }  // if iError
  1052.         break;
  1053.         }  // case BAD_LEFT
  1054.     case BAD_RIGHT :
  1055.         {
  1056.         ReportMismatch("\pMismatched right comment found!");
  1057.         srectTemp.lDisplayTop = -1;                                // minimize scrolling
  1058.         srectTemp.lStartingPos = lCurPos - 2;
  1059.         srectTemp.lEndingPos = lCurPos;
  1060.         iError = faccess(pszFileName,F_SSELINFO,(long *)&srectTemp);
  1061.         if (iError)
  1062.             {
  1063.             (void) ReportError("\pCan't select the mismatched comment","\p");
  1064.             }  // if iError
  1065.         break;
  1066.         }  // case BAD_RIGHT
  1067.     case BAD_NESTED :
  1068.         {
  1069.         ReportMismatch("\pNested C-style “/* */” comment found!");
  1070.         srectTemp.lDisplayTop = -1;                                // minimize scrolling
  1071.         srectTemp.lStartingPos = lCurPos - 2;
  1072.         srectTemp.lEndingPos = lCurPos;
  1073.         iError = faccess(pszFileName,F_SSELINFO,(long *)&srectTemp);
  1074.         if (iError)
  1075.             {
  1076.             (void) ReportError("\pCan't select the nested comment","\p");
  1077.             }  // if iError
  1078.         break;
  1079.         }  // case BAD_NESTED
  1080.     default :
  1081.         {
  1082.         // no mismatched comments
  1083.         fMismatch = false;
  1084.         ReportNoMismatch("\pNo mismatched comments found!");
  1085.         break;
  1086.         }  // default
  1087.     }  // switch iError
  1088. return fMismatch;
  1089. }  // CheckComments()
  1090.  
  1091. void main(int /*argc*/,char **argv)
  1092. {
  1093. char *pszFileName;
  1094. Boolean fDone,fMismatch;
  1095. int iErr,iExit,iMode;
  1096. long lEndPos,lStartPos;
  1097. FILE *pfilActive;
  1098. struct SelectRect srectTemp;
  1099.  
  1100. InitCursorCtl(NULL);
  1101. InitGraf(&qd.thePort);
  1102. InitCursor();
  1103. strcpy(gachToolName,*argv);                                            // save the tool's name
  1104. c2pstr(gachToolName);                                                // make it a p-string
  1105. fMismatch = false;                                                    // initialize
  1106. iExit = 0;                                                            // initialize
  1107. pszFileName = getenv("active");
  1108. iErr = faccess(pszFileName,F_GSELINFO,(long *)&srectTemp);
  1109. if (iErr)
  1110.     {
  1111.     iExit = ReportError("\pCan't read selection information","\p");
  1112.     }  // if iErr
  1113. else
  1114.     {
  1115.     lStartPos = srectTemp.lStartingPos;
  1116.     lEndPos = srectTemp.lEndingPos;
  1117.     if (lStartPos != lEndPos)
  1118.         {
  1119.         // there is a selection
  1120.         srectTemp.lEndingPos = srectTemp.lStartingPos;
  1121.         (void) faccess(pszFileName,F_SSELINFO,(long *)&srectTemp);    // remove the highlighting to work around MPW window update problem
  1122.         }  // if lStartPos
  1123.     pfilActive = fopen(pszFileName,"r");
  1124.     if (pfilActive != NULL)
  1125.         {
  1126.         (void) fseek(pfilActive,lStartPos,SEEK_SET);                // seek to the start of the selected text (if any)
  1127.         (void) setvbuf(pfilActive,NULL,_IOFBF,(8 * BUFSIZ));
  1128.         fDone = PairsDialog(&iMode);
  1129.         if (!fDone)
  1130.             {
  1131.             // OK was pressed - do the indicated pairs checking
  1132.             switch(iMode)
  1133.                 {
  1134.                 case MODE_CURLY_BRACE :
  1135.                 case MODE_SQUARE_BRACE :
  1136.                 case MODE_PARENTHESIS :
  1137.                     {
  1138.                     fMismatch = CheckBraces(iMode,pfilActive,pszFileName,lStartPos,lEndPos);
  1139.                     break;
  1140.                     }  // case MODE_CURLY_BRACE … MODE_PARENTHESIS
  1141.                 case MODE_DBL_QUOTE :
  1142.                 case MODE_SNGL_QUOTE :
  1143.                     {
  1144.                     fMismatch = CheckQuotes(iMode,pfilActive,pszFileName,lStartPos,lEndPos);
  1145.                     break;
  1146.                     }  // case MODE_DBL_QUOTE,MODE_SNGL_QUOTE
  1147.                 case MODE_COMMENT :
  1148.                     {
  1149.                     fMismatch = CheckComments(pfilActive,pszFileName,lStartPos,lEndPos);
  1150.                     break;
  1151.                     }  // case MODE_COMMENT
  1152.                 default :
  1153.                     {
  1154.                     // do nothing
  1155.                     break;
  1156.                     }  // default
  1157.                 }  // switch iMode
  1158.             }  // if !fDone
  1159.         (void) fclose(pfilActive);
  1160.         }  // if pfilActive
  1161.     else
  1162.         {
  1163.         ReportError("\pCan't open file",c2pstr(pszFileName));
  1164.         iExit = 1;
  1165.         }  // else if pfilActive
  1166.     }  // else if iErr
  1167. if (!fMismatch)
  1168.     {
  1169.     srectTemp.lEndingPos = lEndPos;
  1170.     (void) faccess(pszFileName,F_SSELINFO,(long *)&srectTemp);        // restore any original highlighting
  1171.     }  // if !fMismatch
  1172. exit (iExit);
  1173. }  // main()
  1174.  
  1175. // end of Pairs.c